package com.ruoyi.accounts.service.impl;

import com.ruoyi.accounts.service.base.AbstractClientHandler;
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
import com.ruoyi.accounts.tcp.WSCommand;
import javax.websocket.Session;
import org.springframework.stereotype.Service;
import com.ruoyi.accounts.tcp.GameStateService;
import com.ruoyi.accounts.tcp.GameStateEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;

@Service
public class TBJClientHandlerImpl extends AbstractClientHandler{

    private static final Logger LOGGER = LoggerFactory.getLogger(TBJClientHandlerImpl.class);

    private final Set<String> supportedCommands = new HashSet<>(
        Arrays.asList("check", "start", "putCoin", "wiper", "refund")
    );
    
    @Override
    public boolean canHandle(String commandType) {
        return supportedCommands.contains(commandType);
    }
    
    @Override
    public Long getMachineType() {
        return 2L;
    }
    
    @Override
    public void handleCommand(WSCommand command, Session session, String message) throws Exception {
        String commandType = command.getType();
        // 使用switch处理该机器支持的命令
        switch (commandType) {
            case "check":
                handleCheckCommon(command, session);
                break;
            case "start":
                handleStart(command, session, message);
                break;
            case "putCoin":
                handlePutCoin(command, session, message);
                break;
            case "wiper":
                handleWiper(command, session, message);
                break;
            case "refund":
                handleRefund(command, session);
                break;
            // 其他命令处理...
            default:
                sendMessageToSocketClient(session, false, "推币机不支持的命令: " + commandType);
        }
    }

    private void handleStart(WSCommand command, Session session, String message) throws Exception {
        // 实现开始处理逻辑
        // 尝试占机
        if (!GameStateService.tryTakeUp(command.getCustomID(), command.getMachineID())) {
            sendMessageToSocketClient(session, false, "机器被占用");
            return;
        }
        /// 判断状态
        // 有游戏状态，可能是断线重连
        GameStateEnum gameState = GameStateService.getGameState(command.getCustomID());
        // 不需要再次投币
        if (gameState == GameStateEnum.Playing || gameState == GameStateEnum.Waiting) {
            // 告诉客户端
            sendMessageToSocketClient(session, true, "重连成功");
            GameStateService.refresh(command.getCustomID());
            return;
        }
        // 占机成功更新占机时间、游戏状态
        GameStateService.setGameState(command.getCustomID(), GameStateEnum.Playing);
        GameStateService.refresh(command.getCustomID());
        //投币
        // handlePutCoin(command, session, message);
    }

    private void handlePutCoin(WSCommand command, Session session, String message) throws Exception {
        // 实现投币处理逻辑
        // 查询是否占用的当前机器
        if (!GameStateService.isTakeUp(command.getCustomID(), command.getMachineID())) {
            sendMessageToSocketClient(session, false, "机器被占用");
            return;
        }
        try {
            // 存记录进redis在tcp线程中使用、通知投币
            stringRedisTemplate.opsForValue().set(command.getCustomID(), message,120, TimeUnit.SECONDS);
            tcpThreadService.SendPutCoinToMachine(command.getCustomID(), command.getMachineID(), command.getCoins());
        } catch (ExecutionException | InterruptedException e) {
            LOGGER.error(e.getMessage());
            sendMessageToSocketClient(session, false, e.getMessage());
        }
    }

    private void handleWiper(WSCommand command, Session session, String message) throws Exception {
        // 实现雨刮处理逻辑
        // 查询是否占用的当前机器
        if (!GameStateService.isTakeUp(command.getCustomID(), command.getMachineID())) {
            sendMessageToSocketClient(session, false, "机器被占用");
            return;
        }
        try {
            // 存记录进redis在tcp线程中使用、通知投币
            stringRedisTemplate.opsForValue().set(command.getCustomID(), message,120, TimeUnit.SECONDS);
            tcpThreadService.SendWiperToMachine(command.getCustomID(), command.getMachineID());
        } catch (ExecutionException | InterruptedException e) {
            LOGGER.error(e.getMessage());
            sendMessageToSocketClient(session, false, e.getMessage());
        }
    }
    
    // 其他命令处理方法...
}
